package com.ruoyi.activiti.utils;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;

import java.io.*;
import java.util.*;

public class ActivitiUtils {






    public static void resolvTask(ProcessEngine processEngine ,ProcessInstance  task)  {
        instanceALL(processEngine
                ,task.getProcessInstanceId()
                ,task.getProcessDefinitionId()
        );
    }


    public static void resolvTask(ProcessEngine processEngine ,Task task)  {
        instanceALL(processEngine
                ,task.getProcessInstanceId()
                ,task.getProcessDefinitionId()
                );
    }
    public static  FlowNode  activFlowNode(ProcessEngine processEngine , Task task)  {
       return activFlowNode(
                processEngine
                ,task.getProcessInstanceId()
                ,task.getProcessDefinitionId()

        );
    }
    public static  FlowNode  activFlowNode(ProcessEngine processEngine , String processInstanceId , String processDefinitionId)  {
        //获取HistoryService对象
        HistoryService historyService = processEngine.getHistoryService();
        //获取流程实例 历史节点（需要完成）
        List<HistoricActivityInstance> unFinishedlist = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .unfinished()
                .list();
        GrcPocess grcPocess = pocessALL(processEngine.getRepositoryService(), processDefinitionId);

        for (HistoricActivityInstance hActivityInstance : unFinishedlist) {

            return grcPocess.getUserTaskByActivityId( hActivityInstance.getActivityId());

        }
        return  null;
    }

    public static void instanceALL(ProcessEngine processEngine , String processInstanceId , String processDefinitionId)  {

        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) processEngine.getRepositoryService()
                .createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();



        //获取HistoryService对象
        HistoryService historyService = processEngine.getHistoryService();

        //获取流程实例 历史节点（已完成）
        List<HistoricActivityInstance> finishedlist = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .finished()
                .list();

        //获取流程实例 历史节点（需要完成）
        List<HistoricActivityInstance> unFinishedlist = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .unfinished()
                .list();


        for (HistoricActivityInstance hActivityInstance : unFinishedlist) {

            System.out.println(String.format("unHistoricActivityInstance   Id :{%s}  TaskId :{%s}  Assignee: {%s} ActivityId ：{%s}  ActivityName：{%s} "
                    ,hActivityInstance.getId()
                    ,hActivityInstance.getTaskId()
                    ,hActivityInstance.getAssignee()
                    ,hActivityInstance.getActivityId()
                    ,hActivityInstance.getActivityName()
            ));

            TaskService taskService = processEngine.getTaskService();
            List<Task> list = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
            //Holiday holiday = taskService.getVariable(list.get(0).getId(), "holiday", Holiday.class);

            Map<String, Object> env = new HashMap<>();
            env.put("holiday","");
            //System.out.println(holiday);

            GrcPocess grcPocess = pocessALL(processEngine.getRepositoryService(), processDefinitionId);
            System.out.println(grcPocess);
            List<GrcUserTask> nextUserTask = grcPocess.getNextUserTask(hActivityInstance.getActivityId());
            for (GrcUserTask grcUserTask : nextUserTask) {


                String expression = grcUserTask.getConditionExpression();

                Expression compiledExp = AviatorEvaluator.compile(expression);

                Boolean result = (Boolean) compiledExp.execute(env);
                //   boolean isFuture = grcUserTask.getIsFuture(env);
                System.out.println("是否成立："+result);
                System.out.println(grcUserTask);

            }
        }
    }
    public static void instanceALL2(ProcessEngine processEngine , String processInstanceId , String processDefinitionId)  {


        HashMap<String, HistoricActivityInstance> finishedMap = new HashMap<>();
        //获取HistoryService对象
        HistoryService historyService = processEngine.getHistoryService();



        //获取流程实例 历史节点（全部）
        List<HistoricActivityInstance> Allfinishedlist = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .list();
        for (HistoricActivityInstance hActivityInstance : Allfinishedlist) {
            System.out.println(String.format("AllHistoricActivityInstance   Id :{%s}  TaskId :{%s}  Assignee: {%s} ActivityId ：{%s}  ActivityName：{%s} "
                    ,hActivityInstance.getId()
                    ,hActivityInstance.getTaskId()
                    ,hActivityInstance.getAssignee()
                    ,hActivityInstance.getActivityId()
                    ,hActivityInstance.getActivityName()

            ));
            //finishedMap.put(hActivityInstance.getActivityId(),hActivityInstance);
        }

        //获取流程实例 历史节点（已完成）
        List<HistoricActivityInstance> finishedlist = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .finished()
                .list();
        for (HistoricActivityInstance hActivityInstance : finishedlist) {
            System.out.println(String.format("HistoricActivityInstance   Id :{%s}  TaskId :{%s}  Assignee: {%s} ActivityId ：{%s}  ActivityName：{%s} "
                    ,hActivityInstance.getId()
                    ,hActivityInstance.getTaskId()
                    ,hActivityInstance.getAssignee()
                    ,hActivityInstance.getActivityId()
                    ,hActivityInstance.getActivityName()

            ));
            finishedMap.put(hActivityInstance.getActivityId(),hActivityInstance);
        }

        //获取流程实例 历史节点（未完成）
        List<HistoricActivityInstance> unFinishedlist = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .unfinished()
                .list();
        for (HistoricActivityInstance hActivityInstance : unFinishedlist) {
            System.out.println(String.format("unHistoricActivityInstance   Id :{%s}  TaskId :{%s}  Assignee: {%s} ActivityId ：{%s}  ActivityName：{%s} "
                    ,hActivityInstance.getId()
                    ,hActivityInstance.getTaskId()
                    ,hActivityInstance.getAssignee()
                    ,hActivityInstance.getActivityId()
                    ,hActivityInstance.getActivityName()

            ));
        }

        //获取RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        Process process = bpmnModel.getProcesses().get(0);
        //获取所有的FlowElement信息
        Collection<FlowElement> flowElements = process.getFlowElements();



        HashMap<String, SequenceFlow> stringSequenceFlowHashMap = new HashMap<>();
        HashMap<String, FlowElement> stringFlowElementHashMap = new HashMap<>();

        HashMap<String, SequenceFlow> unstringSequenceFlowHashMap = new HashMap<>();
        HashMap<String, FlowElement> unstringFlowElementHashMap = new HashMap<>();


        HashMap<String, SequenceFlow> allstringSequenceFlowHashMap = new HashMap<>();
        HashMap<String, FlowElement> allFlowElementHashMap = new HashMap<>();


        for (FlowElement flowElement : flowElements) {


            if (flowElement instanceof SequenceFlow) {
                SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
                allstringSequenceFlowHashMap.put(sequenceFlow.getId(),sequenceFlow);

                if(finishedMap.containsKey(sequenceFlow.getSourceRef())
                        && finishedMap.containsKey(sequenceFlow.getTargetRef())
                ){
                    stringSequenceFlowHashMap.put(sequenceFlow.getId(),sequenceFlow);
                }else{

                    unstringSequenceFlowHashMap.put(sequenceFlow.getId(),sequenceFlow);
                }
            }

            else{
                allFlowElementHashMap.put(flowElement.getId(),flowElement);
                if(finishedMap.containsKey(flowElement.getId())
                ){
                    stringFlowElementHashMap.put(flowElement.getId(),flowElement);

                }else{
                    unstringFlowElementHashMap.put(flowElement.getId(),flowElement);
                }
                //elements.add(flowElement);
            }
        }
        System.out.println("全部的元素："+allFlowElementHashMap.keySet());
        System.out.println("全部的线："+allstringSequenceFlowHashMap.keySet());
        System.out.println("完成："+finishedMap.keySet());
        System.out.println("完成线条："+stringSequenceFlowHashMap.keySet());
        System.out.println("完成元素："+stringFlowElementHashMap.keySet());

        System.out.println("未完成线条："+unstringSequenceFlowHashMap.keySet());
        System.out.println("未完成元素："+unstringFlowElementHashMap.keySet());


        // 使用默认的程序图片生成器
        ProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
        // 使用默认配置获得流程图表生成器，并生成追踪图片字符流
        InputStream imageStream = processDiagramGenerator.generateDiagram(bpmnModel,
                "png",
                new ArrayList<String>(stringFlowElementHashMap.keySet()) ,
                new ArrayList<String>(stringSequenceFlowHashMap.keySet()),
                "宋体",
                "宋体",
                null,
                1.0
        );



        FileOutputStream fileOutputStream=null;
        try {
            File f= new File("d:" + File.separator  +"png"+ File.separator +processInstanceId+".png") ;
            if(f.exists()){
                f.delete();
            }
            fileOutputStream = new FileOutputStream(f);// 通过对象多态性，进行实例化


            OutputStreamWriter oStreamWriter = new OutputStreamWriter(fileOutputStream,"utf-8");
            // 输出图片内容
            Integer byteSize = 1024;
            byte[] b = new byte[byteSize];
            String line="";
            int len;
            while ((len = imageStream.read(b, 0, byteSize)) != -1) {
               /* line = new String(b,0,len,"utf-8");
                fileOutputStream.write(line.getBytes("utf-8"));*/
                fileOutputStream.write(b,0,len);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(fileOutputStream !=null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(imageStream !=null){
                try {
                    imageStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

    /**
     * 获取流程定义
     * @param repositoryService
     * @param processDefinitionId
     * @return
     */
    public static GrcPocess  pocessALL(RepositoryService repositoryService , String processDefinitionId){
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        Process process = bpmnModel.getProcesses().get(0);
        //获取所有的FlowElement信息


        LinkedList<SequenceFlow> lineList = new LinkedList<SequenceFlow>();
        LinkedList<UserTask> userList = new LinkedList<UserTask>();
        LinkedList<Gateway> gatewayList = new LinkedList<Gateway>();
        LinkedList<StartEvent> startList = new LinkedList<StartEvent>();
        LinkedList<EndEvent> endList = new LinkedList<EndEvent>();

        HashMap<String, FlowElement> idElementMap = new HashMap<>();

        Collection<FlowElement> flowElements = process.getFlowElements();
        classiFication(lineList, userList, gatewayList, startList, endList, idElementMap, flowElements);

        GrcPocess grcPocess = new GrcPocess(bpmnModel,process,lineList,userList,gatewayList,startList,endList,idElementMap);
        return grcPocess;

    }

    private static void classiFication(LinkedList<SequenceFlow> lineList, LinkedList<UserTask> userList, LinkedList<Gateway> gatewayList, LinkedList<StartEvent> startList, LinkedList<EndEvent> endList, HashMap<String, FlowElement> idElementMap, Collection<FlowElement> flowElements) {
        for (FlowElement flowElement : flowElements) {
            idElementMap.put(flowElement.getId(),flowElement);
            //  System.out.println(flowElement.getClass());
            //判断是否是连线
            if (flowElement instanceof SequenceFlow) {
                lineList.add((SequenceFlow) flowElement);
            }
            else if (flowElement instanceof UserTask) {
                userList.add((UserTask) flowElement);
            }

            else  if (flowElement instanceof Gateway ) {
                gatewayList.add((Gateway) flowElement);
            }

            else if (flowElement instanceof StartEvent) {
                startList.add((StartEvent) flowElement);
            }

            else if (flowElement instanceof EndEvent){
                endList.add((EndEvent) flowElement);
            }else{

            }
        }
    }





}
